package com.ksd.pug.controller.login;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ksd.pug.commons.anno.PugLog;
import com.ksd.pug.commons.anno.PugRateLimiter;
import com.ksd.pug.commons.enums.ResultStatusEnumA;
import com.ksd.pug.commons.ex.BussinessException;
import com.ksd.pug.commons.utils.fn.asserts.Vsserts;
import com.ksd.pug.commons.utils.pwd.MD5Util;
import com.ksd.pug.config.interceptor.repeat.RepeatSubmit;
import com.ksd.pug.pojo.SysLoginUser;
import com.ksd.pug.service.jwt.JwtBlackStringService;
import com.ksd.pug.service.user.ISysLoginUserService;
import com.ksd.pug.utils.jwt.JwtTokenUtils;
import com.ksd.pug.vo.LoginUserVo;
import com.pug.redis.config.PugRedisCacheTemplate;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.concurrent.TimeUnit;

/**
 * @author 飞哥
 * @Title: 学相伴出品
 * @Description: 飞哥B站地址：https://space.bilibili.com/490711252
 * 记得关注和三连哦！
 * @Description: 我们有一个学习网站：https://www.kuangstudy.com
 * @date 2022/1/1 23:35
 */
@RestController
@RequiredArgsConstructor
public class LoginController {

    private final ISysLoginUserService sysLoginUserService;
    private final PugRedisCacheTemplate pugRedisCacheTemplate;
    private final JwtBlackStringService jwtBlackListService2;

    /**
     * 不需要密码
     *
     * @param username
     * @return
     */
    @PostMapping("/auth/login")
    @PugLog(title = "登录生成token")
    @RepeatSubmit
    @PugRateLimiter(timeout = 1, limit = 3)
    public LoginUserVo login(String username) {
        Vsserts.isEmptyEx(username, new BussinessException(ResultStatusEnumA.USER_PWR_STATUS_INPUT));
        // 1: 根据username查询用户信息
        LambdaQueryWrapper<SysLoginUser> userLambdaQueryWrapper = new LambdaQueryWrapper<>();
        userLambdaQueryWrapper.eq(SysLoginUser::getUsername, username);
        SysLoginUser user = sysLoginUserService.getOne(userLambdaQueryWrapper);
        // 如果查询用户存在
        if (user != null) {
            // 2: 创建token
            String token = JwtTokenUtils.createToken(user);
            // 3: 创建vo,按需加载封装返回即可
            LoginUserVo loginUserVo = new LoginUserVo();
            loginUserVo.setUserId(user.getId());
            loginUserVo.setToken(token);
            // 写入信息到redis缓存中
            String tokenKey = "sys:user:token:" + token;
            pugRedisCacheTemplate.setCacheObject(tokenKey, token, JwtTokenUtils.REDIS_TOKEN_EXPIRATION, TimeUnit.MILLISECONDS);
            // 返回即可
            return loginUserVo;
        } else {
            // 代表输入账号密码有误
            throw new BussinessException(ResultStatusEnumA.USER_PWR_STATUS);
        }
    }


    @PostMapping("/auth/login/pwd")
    @PugLog(title = "登录生成token")
    @PugRateLimiter(timeout = 1, limit = 3)
    public LoginUserVo login(String username, String password) {
        Vsserts.isEmptyEx(username, new BussinessException(ResultStatusEnumA.USER_PWR_STATUS_INPUT));
        Vsserts.isEmptyEx(password, new BussinessException(ResultStatusEnumA.USER_PWR_STATUS_INPUT));
        // 1: 根据username查询用户信息
        LambdaQueryWrapper<SysLoginUser> userLambdaQueryWrapper = new LambdaQueryWrapper<>();
        userLambdaQueryWrapper.eq(SysLoginUser::getUsername, username);
        SysLoginUser user = sysLoginUserService.getOne(userLambdaQueryWrapper);
        if (user != null) {
            // 把用户输入的密码进行md5假面
            String inputpwd = MD5Util.md5slat(password);
            // 然后把用户输入的加密的密码和数据库中user.getPassword()进行比较
            if (!inputpwd.equalsIgnoreCase(user.getPassword())) {
                throw new BussinessException(ResultStatusEnumA.USER_PWR_STATUS);
            }

            // 2：生成token
            String token = JwtTokenUtils.createToken(user);
            // 3: 创建vo,按需加载封装返回即可
            LoginUserVo loginUserVo = new LoginUserVo();
            loginUserVo.setUserId(user.getId());
            loginUserVo.setToken(token);

            // 写入信息到redis缓存中
            String tokenKey = "sys:user:token:" + token;
            pugRedisCacheTemplate.setCacheObject(tokenKey, token, JwtTokenUtils.REDIS_TOKEN_EXPIRATION, TimeUnit.MILLISECONDS);
            return loginUserVo;
        } else {
            // 代表输入账号密码有误
            throw new BussinessException(ResultStatusEnumA.USER_PWR_STATUS);
        }
    }

    /**
     * 退出登录
     *
     * @param request
     * @return
     */
    @PostMapping("/auth/logout")
    @PugLog(title = "退出登录")
    public String logout(HttpServletRequest request) {
        // 获取请求toekn
        String token = JwtTokenUtils.getJwtToken(request);
        // 把当前token拉入黑名单中
        jwtBlackListService2.addBlackList(token);
        // 返回成功
        return "success";
    }
}
